# -*- coding: utf-8 -*-
''' 这里考虑到不同的彩种可能需要在不同的机器上跑异步任务，所以不同彩票的同一类型的活动是分开的
不同事件。可以考虑将activity_type放在event_msg里面，只定义三个事件。或者使用OO的思路来写。
'''
import json
import logging
from abc import ABCMeta, abstractmethod

from common.utils.types import Enum
from common.cache import redis_cache
from common.utils import id_generator
from common.utils.exceptions import DataError
from future.utils import raise_with_traceback


_LOGGER = logging.getLogger(__name__)


TIMER_EVENT_TYPE = Enum({
    "CQ_SSC_ACTIVITY_START": (1L, "start new term cq_ssc"),
    "ACTIVITY_STOP": (2L, "stop ongoing term"),
    'CALC_STATS': (3L, "calc trend stats"),
    "JS_KS_ACTIVITY_START": (5L, "start new term js_ks"),
    "SD_11X5_ACTIVITY_START": (6L, "start new term sd_11x5"),
    "ACTIVITY_ANNOUNCE": (7L, "announce activity"),
    "TJ_SSC_ACTIVITY_START": (9L, "start new term tj_ssc"),
    "XJ_SSC_ACTIVITY_START": (10L, "start new term xj_ssc"),
    "JX_11X5_ACTIVITY_START": (11L, "start new term jx_11x5"),
    "SH_11X5_ACTIVITY_START": (12L, "start new term sh_11x5"),
    "GX_KS_ACTIVITY_START": (13L, "start new term gx_ks"),
    'GD_11X5_ACTIVITY_START': (14L, "start new term gd_11x5"),
    "BJ_PK10_ACTIVITY_START": (15L, "start new term bj_pk10"),
    "CQ_LF_ACTIVITY_START": (16L, "start new term cq_lf"),
    "TC_PLS_ACTIVITY_START": (17L, "start new term tc_pls"),
    "FC3D_ACTIVITY_START": (18L, "start new term fc3d"),
    "FF_SSC_ACTIVITY_START": (19L, "start new term ff_ssc"),
    "FF_11X5_ACTIVITY_START": (20L, "start new term ff_11x5"),
    "FF_KS_ACTIVITY_START": (21L, "start new term ff_ks"),
    "FF_PK10_ACTIVITY_START": (22L, "start new term ff_pk10"),
    "COUPON_EXPIRED": (30L, "coupon expiration")
})


class TimerEvent(object):
    """Timer event wrapper
    """

    def __init__(self, event_type, event_value, timestamp):
        self.event_type = event_type
        # must be a json dict, like {'id': xxxx, 'msg': xxxx}
        self.event_value = event_value
        self.timestamp = timestamp

    @classmethod
    def submit(cls, event_type, event_msg, timestamp, max_try=None):
        # construct event_value dict
        event_value = {
            'id': id_generator.generate_uuid(),
            'msg': event_msg,
            'max_try': max_try
        }
        try:
            cache_value = json.dumps(event_value)
            redis_cache.submit_timer_event(event_type, cache_value, timestamp)
        except Exception as e:
            _LOGGER.error('timer event submit error.(%s)' % e)
            raise_with_traceback(DataError(e))

        return event_value['id']


class EventHandler(object):

    __metaclass__ = ABCMeta
    MAX_TRY = 0

    @abstractmethod
    def process(self, event):
        pass

    def max_try_callback(self, event_msg):
        """
        如果事件已经达到最大尝试次数，回调该函数
        """
        _LOGGER.fatal('DROP event %s', event_msg)
